﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;


namespace QA_System
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        #region field
        //static protected Stack<sentence_tagger> senStack = new Stack<sentence_tagger>(20);
        static protected Stack<sentence_tagger> senStack_forAnaphora = new Stack<sentence_tagger>(100);
        static protected NPAnaphoraDisCover npAnadis;

        //Bien su dung
        static protected string input = "";
        static protected string output = "";
        static protected string answerText = "";
        static protected action_move_define latest_move = new action_move_define();
        static protected string latest_speaker = "";
        static protected action_move_define next_move = new action_move_define();
        static protected string program_state = "";
        static public SqlConnection DBConnection;

        //path
        static protected string taggedFilePath = QA_System.Properties.Settings.Default.taggedFile;
        static protected string xmlDatabasePath = QA_System.Properties.Settings.Default.xmlDatabasePath;

        // IS type
        static protected Stack<action_move_define> AGENDA = new Stack<action_move_define>();
        static protected Stack<action_move_define> PLAN = new Stack<action_move_define>();
        static protected string[] BEL = new string[20];
        static protected string[] COM = new string[20];
        static protected Stack<string> QUD = new Stack<string>();
        static protected string SPEAKER = "";
        static protected action_move_define MOVES = new action_move_define();



        Stack<action_move_define> plan_find_art = new Stack<action_move_define>(4);
        Stack<action_move_define> plan_find_paint = new Stack<action_move_define>(4);

        static string action_move_type1 = "ask";
        static string action_move_type2 = "answer";
        static string action_move_type3 = "findout";
        static string action_move_type4 = "raise";
        static string action_move_type5 = "greet";
        static string action_move_type6 = "quit";
        static string action_move_type7 = "respond";
        static string action_move_type8 = "consultDB";
        action_move_define greet_move = new action_move_define(action_move_type5);
        action_move_define quit_move = new action_move_define(action_move_type6);


        #endregion

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // plan: ?find_paint
            action_move_define action1 = new action_move_define(action_move_type3, "?.genre");
            action_move_define action2 = new action_move_define(action_move_type3, "?.material");
            action_move_define action3 = new action_move_define(action_move_type3, "?.artist");
            action_move_define action4 = new action_move_define(action_move_type8, "?.find_paint");

            plan_find_paint.Push(action1);
            plan_find_paint.Push(action2);
            plan_find_paint.Push(action3);
            plan_find_paint.Push(action4);

            // plan: ?find_art
            action_move_define action5 = new action_move_define(action_move_type3, "?.nationality");
            action_move_define action6 = new action_move_define(action_move_type3, "?.have_paint");
            action_move_define action7 = new action_move_define(action_move_type8, "?.find_art");

            plan_find_art.Push(action5);
            plan_find_art.Push(action6);
            plan_find_art.Push(action7);            
            AGENDA.Push(greet_move);
            program_state = "run";
            userSen.Text = "";

            //taggerTree.Text = "";
            //ElipseText.Text = "";
            //AnswerText.Visible = true;
            module.selectmodule(ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD);

            //kiem tra trang thái ban dau
            if (next_move.get_types() != "")
            {
                string t = module.generatemodule(next_move);
                answerText = module.outputmodule(t, ref next_move, ref latest_speaker, ref latest_move);
                module.updatemodule(latest_move, latest_speaker, ref program_state, ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD, ref SPEAKER, ref MOVES, plan_find_art, plan_find_paint);
                // taggerTree.Text = "LS: " + latest_speaker + " @ LM: " + latest_move.get_types() + "." + latest_move.get_content() + " / NM: " + next_move.get_types() + "." + next_move.get_content() + " /S: " + SPEAKER + "@ M:" + MOVES.get_types() + "." + MOVES.get_content();
            }
            string tx = "";
            //tx = senStack.Count.ToString() + ". Sys: " + answerText;
            tx = "System : " + answerText;
            conversation.Items.Add(tx);
            Trie.CreateTrieFromXmlFile(xmlDatabasePath + "TRIE_new - Copy.xml");
        }


        private void sendButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                if ((userSen.Text.Length == 0))
                {
                    answerText = "Bạn chưa nhập nội dung. ";
                    //AnswerText.Visible = true;
                }
                else
                {
                    string questionText = "";
                    questionText = "User : " + userSen.Text;
                    conversation.Items.Add(questionText);
                    STRINGCLASS.getSentences(STRINGCLASS.fixword(userSen.Text.Trim()), taggedFilePath + "question.txt");
                    STRINGCLASS.tagger(taggedFilePath + "question.txt", taggedFilePath + "questionTag.xml");
                   
                    //Dang dung ham doc xml cua Ngan 

                    List<sentence_tagger> fixedQuestionSentenceList = new List<sentence_tagger>();
                    List<string> answerList = new List<string>();
                    answerText = "";
                    fixedQuestionSentenceList = STRINGCLASS.readXmlFile2(taggedFilePath + "questionTag.xml");
                    foreach (var fixedQuestionSen in fixedQuestionSentenceList)
                    {
                        List<sentence_tagger> answerSentenceListPerQuestion = new List<sentence_tagger>();
                        //sentence_tagger sentence_after_readXML = _sentence_list[0];
                        //day cau hoi của user vào stack
                        //senStack.Push(fixedQuestionSen);
                        // dua cau hoi vao danh sach nhung cau vua hoi
                        //txt = senStack.Count.ToString() + ". Usr: ";
                        //for (int i = 0; i < (fixedQuestionSen.Sentence_length); i++)
                        //    txt += fixedQuestionSen[i].Word_text.ToString() + " ";
                        
                        bool flag = true;
                        sentence_tagger currentQuestionAfterMerge = new sentence_tagger();
                        string[] keyword_list = new string[4]; //bien de chua tu khoa    
                        //string EAT_string = "";
                        //string path_string = "";
                        string ansTxt = "";
                        string answerPerQuestion = "";
                        TrieScanResult scanResult = new TrieScanResult(); 
                       
                        if ((!questionText.ToLower().Contains("chào")) && (!questionText.ToLower().Contains("tạm biệt")) && ((questionText.EndsWith(".")) || (questionText.EndsWith("?"))))
                        {
                            senStack_forAnaphora.Push(fixedQuestionSen);
                            if (senStack_forAnaphora.Count > 1)
                            {
                                flag = MergeClass.Merge(ref senStack_forAnaphora);                                
                            }
                            currentQuestionAfterMerge = senStack_forAnaphora.Peek();
                        }
                        else
                        {
                            currentQuestionAfterMerge = fixedQuestionSen;
                        }
                                              
                        //duyet TRIE
                        scanResult = Trie.ScanTrieToGetEAT(currentQuestionAfterMerge);
                        //scanResult.EAT = STRINGCLASS.loadXmlTrie(xmlDatabasePath + "TRIE_new.xml", currentQuestionAfterMerge, ref keyword_list);
                        
                        if (!scanResult.EAT.StartsWith("Exception"))
                        {
                            userSen.Text = "";
                            //string[] temp = EAT_path_string.Split('@');
                            //EAT_string = temp[0];
                            //path_string = temp[1];
                            ansTxt = AnswerClass.AnswerString(scanResult.EAT, scanResult.keyword, currentQuestionAfterMerge);                            

                            //hien thi EAT, token tim duoc
                            // answerText += EAT_string + "; Trie node load: " + path_string + "; ";

                            /* trong trương hop neu nguoi dung khong tra loi cau hoi he thong ma dua ra cau tra loi khac
                             * he thong tra loi cau hoi do va xoa toan bo du lieu lien quan den van de vua hoi.
                            AGENDA.Clear();
                            PLAN.Clear();
                            QUD.Clear();
                            for (int i = 0; i < QA_issue.COM_total(COM); i++) COM[i] = null;
                            for (int i = 0; i < QA_issue.COM_total(BEL); i++) BEL[i] = null;
                             */

                            if (PLAN.Count > 0)
                            {
                                module.selectmodule(ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD);
                                if (next_move.get_types() != "")
                                {
                                    string t = module.generatemodule(next_move);
                                    ansTxt = module.outputmodule(t, ref next_move, ref latest_speaker, ref latest_move);
                                    module.updatemodule(latest_move, latest_speaker, ref program_state, ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD, ref SPEAKER, ref MOVES, plan_find_art, plan_find_paint);

                                }

                                if ((latest_move.get_types() == "quit") && (latest_speaker == "sys"))
                                {
                                    AGENDA.Clear();
                                    PLAN.Clear();
                                    QUD.Clear();
                                    for (int i = 0; i < QA_issue.COM_total(COM); i++) COM[i] = null;
                                    for (int i = 0; i < QA_issue.COM_total(BEL); i++) BEL[i] = null;
                                }
                            }
                            
                        }
                        else
                        {
                            Random random = new Random();
                            string[] ex = new string[5];
                            ex[0] = "xin lỗi, tôi không biết.";
                            ex[1] = "tôi không có thông tin này.";
                            ex[2] = "Tôi không hiểu câu hỏi của bạn. Bạn có thể diễn đạt lại câu hỏi không ?";                            
                            ansTxt = ex[random.Next(0, 3)];                            
                            if (program_state == "run")
                            {

                                module.inputmodule(userSen.Text, ref latest_speaker, ref latest_move);
                                userSen.Text = "";
                                module.updatemodule(latest_move, latest_speaker, ref program_state, ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD, ref SPEAKER, ref MOVES, plan_find_art, plan_find_paint);

                            }                            
                            module.selectmodule(ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD);
                            if (next_move.get_types() != "")
                            {
                                string t = module.generatemodule(next_move);
                                ansTxt = module.outputmodule(t, ref next_move, ref latest_speaker, ref latest_move);
                                module.updatemodule(latest_move, latest_speaker, ref program_state, ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD, ref SPEAKER, ref MOVES, plan_find_art, plan_find_paint);
                            }

                            if ((latest_move.get_types() == "quit") && (latest_speaker == "sys"))
                            {
                                AGENDA.Clear();
                                PLAN.Clear();
                                QUD.Clear();
                                for (int i = 0; i < QA_issue.COM_total(COM); i++) COM[i] = null;
                                for (int i = 0; i < QA_issue.COM_total(BEL); i++) BEL[i] = null;
                            }
                            if ((PLAN.Count == 0) && (ansTxt == "")) ansTxt = "Exception : Hệ thống không hiểu câu hỏi .";
                            //answerList.Add(ansTxt);

                        }
                        STRINGCLASS.getSentences(STRINGCLASS.fixword(ansTxt), taggedFilePath + "answer.txt");
                        STRINGCLASS.tagger(taggedFilePath + "answer.txt", taggedFilePath + "answerTag.xml");
                        answerSentenceListPerQuestion = STRINGCLASS.readXmlFile2(taggedFilePath + "answerTag.xml");

                        if (!ansTxt.Contains("Exception") && !ansTxt.Contains("Xin lỗi") && (answerSentenceListPerQuestion.Count < 10))
                            foreach (var sentence_as in answerSentenceListPerQuestion)
                            {
                                senStack_forAnaphora.Push(sentence_as);
                                if (senStack_forAnaphora.Count > 1)
                                    flag = QA_System.MergeClass.Merge(ref senStack_forAnaphora);
                            }
                        foreach (var answerSen in answerSentenceListPerQuestion)
                        {
                            for (int i = 0; i < (answerSen.totalword()); i++) answerPerQuestion += answerSen[i].Word_text.ToString() + " ";
                        }
                        answerList.Add(answerPerQuestion);
                    }

                    answerText = "System : ";
                    foreach (var answerSen in answerList)
                    {
                        answerText += answerSen;
                    }
                    conversation.Items.Add(answerText);
                }

            }
            catch (Exception ex)
            {
                //AnswerText.Visible = true;
                answerText = ex.Message.ToString();
            }
        }

        private void Window_closed(object sender, EventArgs e)
        {
            
        }

        private void Exit_executed(object sender, ExecutedRoutedEventArgs e)
        {
            
            this.Close();
        }

        private void ResetConversation_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void ResetConversation_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //conversation.DataContext;
            conversation.Items.Clear();
            //senStack.Clear();
            senStack_forAnaphora.Clear();
            AGENDA.Clear();
            PLAN.Clear();
            QUD.Clear();
            for (int i = 0; i < QA_issue.COM_total(COM); i++) COM[i] = null;
            for (int i = 0; i < QA_issue.COM_total(BEL); i++) BEL[i] = null;
            action_move_define greet_move = new action_move_define(action_move_type5);
            action_move_define quit_move = new action_move_define(action_move_type6);
            AGENDA.Push(greet_move);
            program_state = "run";
            userSen.Text = "";
            answerText = "";
            next_move.set_type("");
            latest_move.set_type("");
            latest_speaker = "";
            module.selectmodule(ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD);
            //kiem tra trang thái ban dau
            if (next_move.get_types() != "")
            {
                string t = module.generatemodule(next_move);
                answerText = module.outputmodule(t, ref next_move, ref latest_speaker, ref latest_move);
                module.updatemodule(latest_move, latest_speaker, ref program_state, ref next_move, ref AGENDA, ref PLAN, ref BEL, ref COM, ref QUD, ref SPEAKER, ref MOVES, plan_find_art, plan_find_paint);
                // taggerTree.Text = "LS: " + latest_speaker + " @ LM: " + latest_move.get_types() + "." + latest_move.get_content() + " / NM: " + next_move.get_types() + "." + next_move.get_content() + " /S: " + SPEAKER + "@ M:" + MOVES.get_types() + "." + MOVES.get_content();
            }
            string tx = "System : " + answerText;
            conversation.Items.Add(tx);
        }

        private void enterPressed(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                sendButton_Click(new object(), new RoutedEventArgs());
                userSen.Text = "";
            }
        }

        private void AboutDialog_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void AboutDialog_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            About about = new About();
            about.ShowDialog();
        }
    }
}
